#include "HuffmanCompressor.h"
#include <iostream>
#include <string>
#include <filesystem>

using namespace std;
namespace fs = std::filesystem;

// 帮助栏打印函数
void help_menu();

int main() {
    HuffmanCompressor compressor;
    string currentLocation = ""; // 当前工作位置

    while (true) {
        // 动态修改提示符
        if (!currentLocation.empty()) {
            cout << currentLocation << "> ";  // 当前工作位置为 newlocation
        }
        else {
            cout << "> ";  // 未设置工作位置时的默认提示符
        }

        string command;
        getline(cin, command);

        if (command.substr(0, 2) == "cd") {
            // 处理cd命令，改变当前工作位置
            string newLocation = command.substr(3);
            if (fs::exists(newLocation) && fs::is_directory(newLocation)) {
                currentLocation = newLocation;
            }
            else {
                cout << "Invalid location." << endl;
            }
        }

        else if (command.substr(0, 4) == "huff") {
            // 处理huff命令，压缩文件
            if (currentLocation.empty()) {
                cout << "Please set working location first with 'cd' command." << endl;
                continue;
            }

            // 提取待压缩文件名和压缩包名
            string input = command.substr(5);
            size_t spacePos = input.find(' ');
            if (spacePos != string::npos) {
                string compressedFile = input.substr(0, spacePos);
                string fileName = input.substr(spacePos + 1);

                // 判断压缩包类型是否正确(.huff)
                if (!(compressedFile.size() >= 5 && compressedFile.substr(compressedFile.size() - 5) == ".huff")) {
                    // 文件不以 '.huff' 结尾
                    cout << "The compressed file name must end with a '.huff' extension." << endl;
                    continue;
                }

                // 判断待压缩文件是否存在
                if (!(fs::exists(currentLocation + "\\" + fileName))) {
                    cout << "Invalid file parameter. Please make sure the target file exist." << endl;
                    continue;
                }

                // 设置压缩目标位置
                compressor.setTargetLocation(currentLocation);
                cout << "Set the location for the compressed file: ";
                string compressLocation;
                cin >> compressLocation;

                if (fs::exists(compressLocation) && fs::is_directory(compressLocation)) {
                    compressor.setHuffLocation(compressLocation);
                    compressor.compressFile(fileName, compressedFile);
                }
                else {
                    cout << "Invalid location." << endl;
                }

                cin.ignore();  // 忽略换行符
            }
            else {
                cout << "Invalid 'huff' command syntax. Usage: huff <compressedFileName> <fileToCompress>" << endl;
            }
        }

        else if (command.substr(0, 6) == "unhuff") {
            // 处理unhuff命令，解压文件
            if (currentLocation.empty()) {
                cout << "Please set working location first with 'cd' command." << endl;
                continue;
            }

            // 提取待解压的压缩包名
            string compressedFile = command.substr(7);

            // 判断待压缩包是否存在
            if (!(fs::exists(currentLocation + "\\" + compressedFile) && fs::is_regular_file(currentLocation + "\\" + compressedFile))) {
                cout << "Invalid file parameter. Please make sure the target file exist." << endl;
                continue;
            }

            // 判断待压缩包类型是否正确(.huff)
            if (!(compressedFile.size() >= 5 && compressedFile.substr(compressedFile.size() - 5) == ".huff")) {
                // 文件不以 '.huff' 结尾
                cout << "The compressed file name must end with a '.huff' extension." << endl;
                continue;
            }

            // 设置解压目标位置
            compressor.setHuffLocation(currentLocation);
            cout << "Set the location for the new content after decompression: ";
            string decompressLocation;
            cin >> decompressLocation;

            if (fs::exists(decompressLocation) && fs::is_directory(decompressLocation)) {
                compressor.setUnHuffLocation(decompressLocation);
                compressor.decompressFile(compressedFile);
            }
            else {
                cout << "Invalid location." << endl;
            }
            
            cin.ignore();  // 忽略换行符
        }

        else if (command == "dir") {
            // 列出当前工作目录中的所有子目录和子文件
            if (fs::is_empty(currentLocation)) { // 空目录
                cout << "empty directory" << endl;
                continue;
            }
            if (currentLocation.empty()) {
                cout << "Please set working location first with 'cd' command." << endl;
                continue;
            }
            cout << "Listing files and directories in: " << currentLocation << endl;
            for (const auto& entry : fs::directory_iterator(currentLocation)) {
                if (fs::is_directory(entry)) {
                    cout << "[DIR]  " << entry.path().filename().string() << endl;
                }
                else if (fs::is_regular_file(entry)) {
                    cout << "[FILE] " << entry.path().filename().string() << endl;
                }
            }
        }

        else if (command == "help") {
            // 显示帮助信息
            help_menu();
        }

        else if (command == "exit") {
            // 退出程序
            break;
        }

        else if (command == "") {
            // 处理空指令
            ;
        }

        else {
            // 处理非法指令
            cout << "Unknown command. Available commands: cd, huff, unhuff, exit." << endl;
        }
    }

    return 0;
}

void help_menu() {
    cout << "Welcome to use this file compressor. To better use it, please read this help carefully at first. " << endl;
    cout << "Help - Available Commands:" << endl;
    cout << "1. cd <path>" << endl;
    cout << "   - Changes the current working directory to <path>." << endl;
    cout << "   - <path> should be a valid directory path." << endl;
    cout << "   - If the directory does not exist, or the path is invalid, an error will be shown." << endl;
    cout << "   - Example usage: cd C:\\Users\\Documents\\Files" << endl;
    cout << endl;

    cout << "2. huff <compressedFileName> <fileToCompress>" << endl;
    cout << "   - Compresses <fileToCompress> into a compressed file named <compressedFileName>." << endl;
    cout << "   - The <compressedFileName> must end with a '.huff' extension." << endl;
    cout << "   - <fileToCompress> should be a valid file located in the current working directory." << endl;
    cout << "   - The program will prompt you to specify the directory to store the compressed file." << endl;
    cout << "   - If the compressed file name does not have the .huff extension, an error will occur." << endl;
    cout << "   - Example usage: huff archive.huff myfile.txt" << endl;
    cout << "   - The program will then ask for the location where the .huff file should be saved." << endl;
    cout << endl;

    cout << "3. unhuff <compressedFileName>" << endl;
    cout << "   - Decompresses the .huff compressed file <compressedFileName>." << endl;
    cout << "   - The <compressedFileName> must be a valid .huff file located in the current working directory." << endl;
    cout << "   - The program will prompt you to specify the directory where the decompressed files should be saved." << endl;
    cout << "   - If the file does not exist or the extension is incorrect, an error will occur." << endl;
    cout << "   - Example usage: unhuff archive.huff" << endl;
    cout << "   - The program will then ask for the location where the decompressed files should be placed." << endl;
    cout << endl;

    cout << "4. dir" << endl;
    cout << "   - Lists all files and directories in the current working directory." << endl;
    cout << "   - If no directory is set (i.e., the working directory is empty), an error message will be shown." << endl;
    cout << "   - Example usage: dir" << endl;
    cout << "   - The program will show all files and subdirectories in the current location." << endl;
    cout << endl;

    cout << "5. exit" << endl;
    cout << "   - Exits the program." << endl;
    cout << "   - Example usage: exit" << endl;
    cout << endl;

    cout << "General Notes:" << endl;
    cout << "   - Before using 'huff' or 'unhuff', you must set the current working directory using 'cd'." << endl;
    cout << "   - The program will not work unless the working directory is set." << endl;
    cout << "   - All file operations (such as compression and decompression) assume that the file is in the current working directory." << endl;
    cout << "   - Ensure that the target file is valid before attempting compression or decompression." << endl;
    cout << "   - Use the 'dir' command to verify the files and directories available in your current location." << endl;
    cout << endl;

    cout << "Example Workflow:" << endl;
    cout << "   1. Use 'cd' to set your working directory." << endl;
    cout << "   2. Use 'dir' to list available files and directories." << endl;
    cout << "   3. Use 'huff' to compress a file into a .huff archive." << endl;
    cout << "   4. Use 'unhuff' to decompress a .huff archive into files." << endl;
    cout << "   5. Exit the program when finished using 'exit'." << endl;
}
